home *** CD-ROM | disk | FTP | other *** search
- Tips and Tricks for Macsbug
-
- All of us who program on the Macintosh have lots of little tricks that we
- use to get our job done. Most of these are passed around via e-mail and the
- Usenet News, if they are passed on at all. In an effort to collect all these
- in one place for the benefit of all, I've created this page. Please submit
- your tips to crawford@scruznet.com and I will add them to this page - with
- proper attribution of course.
-
- Contents
-
- Where to get Macsbug
- Are there books that teach how to use Macsbug?
- Debugging Software on the Macintosh
- How to get Macsbug help for free
- Breaking While a Particular Application is Executing
- Logging Program Execution
- Logging Data in Real Time
- Using Cursors to Trace Program Execution
- Using Touch and Go Breakpoints with Two Monitors
- Twiddling Pixels in the Menu Bar
- Forcing Testers to Use Macsbug During Beta Testing
- The Developer University Debugging Class
- Links to Other Macsbug Pages
-
- Where to get Macsbug
-
- Macsbug is available via anonymous FTP from Apple Computer from here or
- here. It is included with the two books below, but you will want to get
- the latest version, especially if you are using a PowerPC.
-
- Are there books that teach how to use Macsbug?
-
- Yes, among them are:
-
- o Othmer and Strauss, Debugging Mac Software with Macsbug,
- Addison-Wesley 1991, ISBN 0201570491. Macsbug included on disk.
- o Apple Computer Inc., Macsbug Reference and Debugging Guide version
- 6.2, Addison-Wesley 1991, ISBN 0201567687. Macsbug 6.2 included on
- disk.
-
- While you don't need to know how to write assembly code to use Macsbug
- effectively, you will need to know how to read and understand it. Thus
- you will also need to get assembly code reference manuals, such as:
-
- o Kacmarcik, Optimizing PowerPC Code, Addison-Wesley 1995, ISBN
- 0201408392.
- o Motorola, M68000UM/AD MC68000 8/16/32-Bit MPU User Manual,
- Motorola Literature Distribution, 1991.
-
- All of these books may be ordered from the Computer Literacy Bookstore.
-
- How to get Macsbug help for free
-
- Contributed by Bill Coderre, bc@wetware.com
-
- 1. Install Macsbug and programmer's key
- 2. Reboot the machine. Don't start any apps yet.
- 3. Hit CMD-POWER
- 4. type "log Macsbug Help <RETURN>"
- 5. type "help<RETURN>"
- 6. Push space until done.
- 7. type "log<RETURN>"
- 8. type "g<RETURN>"
- 9. Find the file called Macsbug Help on your desktop. Open it with a
- text editor. Read it.
-
- Breaking while a particular application is executing
-
- Most applications call WaitNextEvent. While an application is
- executing, a Pascal string with the name of the application is placed
- at location 0x910. Thus the first four characters of the name itself
- begin at location 0x911. Suppose you want to break while SimpleText is
- active. Enter Macsbug and give the command:
-
- atb WaitNextEvent 911^ = 'Simp'
-
- then continue. You will shortly drop into Macsbug at SimpleText's
- WaitNextEvent call. This is particularly useful when debugging faceless
- background applications. If the application does not call
- WaitNextEvent, try GetNextEvent instead.
-
- Logging Program Execution
-
- Contributed by Darren Giles, Terran Interactive, mars@netcom.com
-
- Always on the lookout for useful debugging tools & tips, I'd love to
- share ideas with others on the topic. I'll start out by offering a
- snippet I've found very useful -- hopefully others will do the same.
-
- One thing that's really bugged me about MacsBug on PPC is that the
- stack crawl has become a much less useful tool. The snippet below gives
- you the ability to keep track of a list of the last significant points
- your program has visited. It's a list, not a stack, so you can also see
- patterns of execution.
-
- Hardly rocket science, but useful & easy to add. Just call
- DEBUG_STUFF_INIT at startup, then insert a DEBUG_ENTRY wherever you
- want. To see what's up, especially during a bad hang, just dm [the
- address that DEBUG_STUFF_INIT dumped out at startup.]
-
- The conditional compilation means that if you turn of debugging in your
- final build, the release version of the program won't have any of this
- code in it.
-
- [debugstuff.h]
- #define DB_ROUTINES_NBR_ENTRIES 40
- #define DB_ROUTINES_CHARS 16
- typedef char db_routine_entry[DB_ROUTINES_CHARS];
- #if DEBUGGING
- void DEBUG_ENTRY (char *txt);
- void DEBUG_STUFF_INIT (char *title);
- #else
- #define DEBUG_ENTRY
- #define DEBUG_STUFF_INIT
- #endif
-
- [debugstuff.c]
- ///////////////////////////////////////////////////////////////////////
- ////
- #if DEBUGGING
- void DEBUG_STUFF_INIT (char *title) {
- OSErr myErr;
- char txt[256];
- long response;
-
-
- if (!MacsBugInstalled()) {
- hi_notify ("MacsBug is not installed… the debugging log will be
- inaccessible.");
- }
-
- g_debug_entries= (db_routine_entry*) NewPtrClear
- ((DB_ROUTINES_NBR_ENTRIES+2) * DB_ROUTINES_CHARS);
- memset (&g_debug_entries[0], '=', DB_ROUTINES_CHARS);
- BlockMoveData (title, &g_debug_entries[0], strlen(title));
- memset (&g_debug_entries[DB_ROUTINES_NBR_ENTRIES+1], '=',
- DB_ROUTINES_CHARS);
- sprintf (txt, "Debugging routine list is at 0x%lx;g", (long)
- g_debug_entries);
- c2pstr (txt);
- DebugStr (txt);
- }
- #endif
-
- ///////////////////////////////////////////////////////////////////////
- ////
- // This leaves a line in the debugging entry log.
- // For example, important enter/exit points of routines
- ///////////////////////////////////////////////////////////////////////
- ////
- #if DEBUGGING
- void DEBUG_ENTRY (char *txt) {
- short len;
-
-
- // Move the previous entries down one
- BlockMoveData (&g_debug_entries[1], &g_debug_entries[2],
- (DB_ROUTINES_NBR_ENTRIES-1) * DB_ROUTINES_CHARS);
-
- // Clear the new space
- memset (&g_debug_entries[1], 0, DB_ROUTINES_CHARS);
-
- // Copy in the new entry
- len= strlen (txt);
- if (len > DB_ROUTINES_CHARS) {
- len= DB_ROUTINES_CHARS;
- }
- BlockMoveData (txt, &g_debug_entries[1], len);
- }
- #endif
-
- Hope this does someone some good.
-
- - Darren
-
- ==========================================================================
- Darren Giles, Technical Director Terran Interactive
- For info on Cleaner QuickTime compression, visit http://www.terran-int.com
-
- Logging Data in Real Time
-
- Contributed by Dave Stone, dstone@chem.utoronto.ca
-
- I've also used conditional compilation to debug serial communications
- stuff being processed at interrupt time - something like
-
- #ifdef DEBUG_MY_ROUTINE
- #define MAX_BUFFER 10000
- char bufffer[MAX_BUFFER]; // or NewPtr it or something
- long bufCount = 0L;
- #endif
- .
- .
- .
- #ifdef DEBUG_MY_ROUTINE
- if(bufCount < MAX_BUFFER) {
- bufCount ++;
- buffer[bufCount] = ch; // ch is a character read/written through serial
- port
- }
- #endif
-
- etc. Handy, because you can let it rip for a while to see if there is a
- consistent pattern in the errors in ch - in my case, a stream of Midi
- data through a very basic freeware Midi Driver.
-
- Using Cursors to Trace Program Execution
-
- Contributed by Tom Kimpton, Jostens Learning Corporation, tom@jlc.com
-
- One technique that I have used in the past where dropping into the
- debugger wasn't an option, and logging wasn't getting flushed in
- time/took too long, was to create a bunch of cursors numbering 00 - 99,
- and made a call to set the cursor and return the number of the previous
- cursor:
-
- routine1()
- {
- short oldCursor = setDebugCursor(15);
- ...
- (void) setDebugCursor(oldCursor);
- }
-
- This way when the machine froze, the cursor would tell me what routine
- it had frozen in.
-
- Using Touch and Go Breakpoints with Two Monitors
-
- I had a bug in which the Mac would occasionally freeze during shutdown
- without the ability to get into Macsbug. It would only occur about once
- in twenty reboots.
-
- The way I dealt with this was to borrow a display card and hook two
- monitors up to the Macintosh. You can use the Monitors control panel to
- select which monitor will be used for Macsbug (hold the option key and
- drag the happy Mac around).
-
- I wrote a small application that just called ShutDownRestart(), and
- placed it in the Startup Items folder. Thus, when the Mac came up into
- the Finder it would immediately reboot. About every twenty minutes it
- would freeze.
-
- If you define a macro named FirstTime in the Debugger Prefs file,
- Macsbug will execute it when it loads. I used a macro that was
- something like:
-
- swap; atr; atb shutdownrestart ";atb Newhandle ";g";g";g
-
- or some such. The swap command caused Macsbug to be permanently left on
- the second screen. That way when the crash occurred you could still see
- the last few things Macsbug did. The ";g" following the a-trap break
- commands tells Macsbug to continue after the break - this is a "Touch
- and Go" breakpoint.
-
- One thing you can also do inside a touch and go breakpoint is set new
- breakpoints. I would take guesses on what traps might be called in the
- neighborhood of the crash, and have breakpoints set on them when
- ShutDownRestart was called.
-
- Then I could leave the Mac rebooting on its own in the lab, and pop in
- every half an hour to check the log, adjust the breakpoints and start
- it up again.
-
- The actual bug took about five months to find and fix.
-
- Twiddling Pixels in the Menu Bar
-
- Contributed by Dave Fleck, Wacom Technology Corp., dfleck@wacom.com
-
- Here's my debugging tip.
-
- I do drivers, and you just plain can't set a breakpoint in ADB
- completion routines (freezes the keyboard so MacsBug is worthless!).
-
- So I throw one of the routines below into the routine to see when a
- piece of code gets executed.
-
- What does it do? It "lights up" a bar (length dependant on screen
- resolution) in the menu bar. So if you DotToggle(300); you get a
- flashing short line in the menu bar.
-
- void DotOn(long where) {
- long *dot;
- dot = (long *)(LMGetScrnBase() + where);
- *dot |= -1;
- }
- void DotOff(long where) {
- long *dot;
- dot = (long *)(LMGetScrnBase() + where);
- *dot &= 0;
- }
- void DotToggle(long where) {
- long *dot;
- dot = (long *)(LMGetScrnBase() + where);
- *dot ^= -1;
- }
-
- dave
-
- -----------------------------------------------------------------
- Dave Fleck email:dfleck@wacom.com phone:360-750-8882x154
- Wacom Technology Corp. sales@wacom.com
- 501 S.E. Columbia Shores Blvd, #300 support@wacom.com
- Vancouver, WA 98661 WWW/FTP:wacom.com
- ------------------------------------------------------------------
-
- Forcing Testers to Use Macsbug During Beta Testing
-
- Contributed by Harold Ekstrom, the ag group, inc., ekstrom@aggroup.com.
-
- Don't you just hate it when beta testers say "it crashes" but don't
- give you any more information? First, tell them to use the "stdlog"
- command in MacsBug, then force them to install MacsBug by checking for
- it during your program's initialization:
-
- --- DebugUtils.h ---
-
- #pragma once
-
- // Debugger types.
- typedef enum DebuggerType {
- kNoDebugger,
- kMacsBug,
- kTMON,
- kOtherDebugger
- } DebuggerType;
-
- Boolean GetDebuggerInfo( DebuggerType *outDebuggerType,
- UInt16 *outDebuggerSignature );
-
- --- DebugUtils.c ---
-
- // Private defines for some low memory globals.
- #define MacJmp ((Ptr *)0x0120) // MacsBug jumptable [pointer].
- #define MacJmpByte ((UInt8 *)0x0120) // MacsBug flags in 24 bit mode [byte].
- #define MacJmpFlag ((UInt8 *)0x0BFF) // MacsBug flag [byte].
-
- // Debugger flag bits.
- #define kDebuggerInstalledBit 5
-
- //
- ---------------------------------------------------------------------------------
- //
- //
- ---------------------------------------------------------------------------------
-
- Boolean
- GetDebuggerInfo(
- DebuggerType * outDebuggerType,
- UInt16 * outDebuggerSignature )
- {
- Boolean theResult = false;
- SInt32 theResponse;
-
- // Initialize return values to defaults.
- *outDebuggerType = kNoDebugger;
- *outDebuggerSignature = ' ';
-
- if ( Gestalt( gestaltAddressingModeAttr, &theResponse ) == noErr ) {
-
- UInt16 theDebugFlags;
-
- // As documented in the "Macsbug Reference & Debugging Guide", page 412
- // if we have a 32 bit capable Memory Manager, debugger flags are at 0x0BFF
- // if we have a 24 bit capable Memory Manager, debugger flags are at 0x0120
-
- if ( (theResponse & (1L << gestalt32BitCapable)) != 0 ) {
- theDebugFlags = *MacJmpFlag;
- } else {
- theDebugFlags = *MacJmpByte;
- }
-
- if ( (theDebugFlags & (1L << kDebuggerInstalledBit)) != 0 ) {
-
- Ptr theDebuggerEntry;
- Ptr theROMBaseWorld;
-
- // There is a debugger installed.
- theResult = true;
-
- // Get the debugger entry.
- theDebuggerEntry = StripAddress( *MacJmp );
-
- // Get the ROM base.
- theROMBaseWorld = StripAddress( LMGetROMBase() );
-
- // Compare the debugger entry to the ROM base.
- if ( theDebuggerEntry < theROMBaseWorld ) {
-
- UInt16 **theDebuggerWorld;
-
- // It's not a ROM based debugger.
- // Get the debugger world.
- theDebuggerWorld = (UInt16 **) StripAddress( theDebuggerEntry - sizeof(Ptr) );
-
- // Get the debugger signature.
- *outDebuggerSignature = **theDebuggerWorld;
-
- // Get the debugger type.
- switch ( *outDebuggerSignature ) {
-
- case 'MT':
- *outDebuggerType = kMacsBug;
- break;
-
- case 'WH':
- *outDebuggerType = kTMON;
- break;
-
- default:
- *outDebuggerType = kOtherDebugger;
- break;
-
- }
-
- }
-
- }
-
- }
-
- return theResult;
- }
-
- Check for a low level debugger like this:
-
- #if BETA_VERSION
- DebuggerType theDebuggerType;
- UInt16 theDebuggerSig;
- if ( !GetDebuggerInfo( &theDebuggerType, &theDebuggerSig ) ) {
- HaltRotateCursor( gRotateCrsr );
- StopAlert( go_get_macsbug_alrt, nil );
- ExitToShell();
- }
- #endif
-
- The Developer University Debugging Class
-
- Contributed by Malcolm Teas, Blaze Technology, mhteas@btech.com
-
- As the instructor and developer of Apple's Developer University class
- called "Macintosh Debugging Tips and Techniques" I would like to make
- sure your tips page references this class.
-
- This class is centered around MacsBug as the easiest to learn low-level
- debugger. It also covers a multitude of low-level topics like memory
- maps, subroutine calling protocols, code segments and code fragments,
- reading (and understanding) assembler for 68K and PPC, and many more
- areas. One key area is how to avoid bugs in the first place. All the
- information you need to be able to debug software at the low-level.
-
- The class is available from Apple's Developer University.
-
- Another thing I want to mention is the version number of the most
- current MacsBug is 6.5.3 (as of this writing). This version includes
- the PPC commands and features.
-
- [I have taken this class and recommend it highly - Mike]
-
- Links to Other Macsbug Pages
-
- o Cool MacsBug Tricks (an informal guide)
- o Macsbug Use
- o Develop Issue 22: Balance of Power: MacsBug for PowerPC
- o Macsbug 6.5.2 Help
- o Macintosh Programming Books
- o Guide to Mac Tools
- o Macintosh Technical Q&A's
- o comp.sys.mac.programming FAQ
- o Macintosh Testing and Quality Control Tools
- o Development and Debugging Tools for the Macintosh
-
-